<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <style>
        body{
            background: rgb(255, 255, 255);
        }
        .game {
            display: grid;
            width: 500px;
            height: 500px;

            grid-template-columns: repeat(4, 1fr);
            grid-template-rows: repeat(4, 1fr);

            gap: 10px;
            margin: calc(50vh - 250px) auto;

            padding: 20px;

        }

        .card-container {
            position: relative;
            perspective: 1000px;
            cursor: pointer;
            width: 100%;
            height: 100%;
            

            border-radius: 20px;
            transition: all 0.2s ease-in-out;
        }

        .card-container:hover {
            box-shadow: 2px 1px 14px rgb(110, 110, 110);
            transform: scale(1.05);
        }

        .back,
        .cover {
            width: 100%;
            height: 100%;
            position: absolute;
            backface-visibility: hidden;
            transition: all 0.3s ease-in-out;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 2.5em;
            border-radius: 7px;
        }

        .cover {
            font-size: 1em;
        }


        .cover {

            background: repeating-linear-gradient(-45deg,
                    #eee,
                    rgb(160, 160, 160) 1px,
                    #d1d1dd 13px);
            transform: rotateY(0deg);
        }

        .back {
            background-color: yellow;
            transform: rotateY(-180deg);
        }

        .active .cover {
            transform: rotateY(180deg);
        }

        .active .back {
            transform: rotateY(0deg);
        }
    </style>
</head>

<body>
    <div class="game">

    </div>



    <script>
        class cardTrack {
            constructor() {
                this.cardList = [];
                this.maxCard = 2;
            }
            handle(el) {
                if(el.hasOpened()) return;
                if (el.isFixed) return;
                if (this.cardList.length === 2) return;

                this.cardList.push(el);
                el.toggleOpen();


                if (this.cardList.length == 2) {
                    if (this.cardList[0].txt !== this.cardList[1].txt) {
                        setTimeout(function (list) {
                            list[0].toggleOpen();
                            list[1].toggleOpen();
                        }.bind(this, [...this.cardList]), 600)
                    } else {
                        this.cardList[0].toggleFixed();
                        this.cardList[1].toggleFixed();
                    }

                    this.cardList = [];
                    return;
                }
            }
        }

        class card extends DocumentFragment {
            constructor(txt, callback) {
                super();
                this.txt = txt;
                this.isFixed = false;
                this.init(txt, callback);
            }

            init(txt, callback) {
                let node = document.createElement("div");
                node.classList.add("card-container");


                let cover = document.createElement("div");
                cover.classList.add("cover");


                let back = document.createElement("div");
                back.classList.add("back");
                back.innerHTML = txt;

                node.append(cover, back);

                this.appendChild(node);

                this.toggleFixed = function () {
                    this.isFixed = true;
                }

                this.hasOpened = function(){
                    return node.classList.contains("active")
                }
                this.toggleOpen = function () {
                    node.classList.toggle("active");

                }
                node.addEventListener("click", () => {
                    callback.handle(this)
                });
            }
        }

        const track = new cardTrack();

        let emoji = ["🏉", "🥙", "🧀", "🥓", "🍱", "🍤", "🍪", "🌞"];
        emoji = [...emoji, ...emoji].map(item => new card(item, track));

        Array.prototype.shiffle = function () {

            for (let i = this.length - 1; i > 0; i--) {
                let j = Math.floor(Math.random() * (i + 1));
                [this[i], this[j]] = [this[j], this[i]]
            }

        }

        emoji.shiffle();

        emoji.forEach(item => {
            document.querySelector(".game").appendChild(item);
        })
    </script>
</body>

</html>